﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;


namespace Xtensible.Extensions.Mapping.Tests
{
    public class TestClass
    {
        private int _x;

        public int this[int index]
        {
            get { return _x; }

            set { _x = value; }
        }

        public string MyString { get; set; }
        public int MyInt { get; set; }
        public int MyInt2 { get; set; }
        public int? MyNullableInt { get; set; }
        public DateTime? MyDate { get; set; }
        public TestClass Child { get; set; }

    }

    public class TestClassDTO
    {
        public string MyString { get; set; }
        public int MyInt { get; set; }
        public int? MyNullableInt { get; set; }
        public DateTime? MyDate { get; set; }
        public int SpecialName { get; set; }
        public int ChildMyInt { get; set; }
        public int CMyInt { get; set; }
    }

    public class ClassWithNoDefaultConstructorX
    {
        internal ClassWithNoDefaultConstructorX(int x)
        {
            X = x;
        }

        public int X { get; set; }
    }

    public class ClassWithNoDefaultConstructorY
    {
        internal ClassWithNoDefaultConstructorY(int y)
        {
            Y = y;
        }

        public int Y { get; set; }
    }


    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class Tests
    {
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        #region Additional test attributes

        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //

        #endregion

        [TestMethod]
        public void Copy_Default_Constructor()
        {
            var source = new TestClass
                             {
                                 MyDate = DateTime.Parse("1/1/2001"),
                                 MyInt = 42,
                                 MyInt2 = 24,
                                 MyNullableInt = 99,
                                 MyString = "test"
                             };
            var destination = source.Map<TestClassDTO>();

            Assert.AreEqual(source.MyDate, destination.MyDate);
            Assert.AreEqual(source.MyInt, destination.MyInt);
            Assert.AreEqual(source.MyNullableInt, destination.MyNullableInt);
            Assert.AreEqual(source.MyString, destination.MyString);
        }

        [TestMethod]
        public void Copy_Parameter_Constructor()
        {
            var source = new ClassWithNoDefaultConstructorX(5);
            var destination = new ClassWithNoDefaultConstructorX(7);

            destination = source.Map(destination);

            Assert.AreEqual(source.X, destination.X);
        }

        [TestMethod]
        public void Copy_And_Transform_Default_Constructor_Singe_Type_Data_Trigger()
        {
            var source = new TestClass {MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24};
            var destination = source.WithTypeTrigger(typeof (string), s => s ?? String.Empty).Map<TestClassDTO>();


            Assert.AreEqual(source.MyDate, destination.MyDate);
            Assert.AreEqual(source.MyInt, destination.MyInt);
            Assert.AreEqual(destination.MyNullableInt, destination.MyNullableInt);
            Assert.AreEqual(destination.MyString, "");
        }


        [TestMethod]
        public void Copy_And_Transform_Default_Constructor_Multiple_Type_Triggers()
        {
            var source = new TestClass {MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24};

            var destination = source.WithTypeTrigger(typeof(string), s => s ?? String.Empty)
                                    .WithTypeTrigger(typeof(int?), i => i ?? default(int))
                                    .Map<TestClassDTO>();
              

            Assert.AreEqual(source.MyDate, destination.MyDate);
            Assert.AreEqual(source.MyInt, destination.MyInt);
            Assert.AreEqual(destination.MyNullableInt, default(int));
            Assert.AreEqual(destination.MyString, "");
        }

        [TestMethod]
        public void Copy_And_Transform_Default_Constructor_Multiple_Type_Triggers_With_Exclusions()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24 };
            var destination = source.WithTypeTrigger(typeof(string), s => s ?? String.Empty)
                                    .WithTypeTrigger(typeof (int?), i => i ?? default(int))
                                    .WithExclusion("MyDate")
                                    .Map<TestClassDTO>();
            

            Assert.AreNotEqual(source.MyDate, destination.MyDate);
            Assert.AreEqual(source.MyInt, destination.MyInt);
            Assert.AreEqual(destination.MyNullableInt, default(int));
            Assert.AreEqual(destination.MyString, "");
            
        }

        [TestMethod]
        public void Copy_And_Transform_Default_Constructor_On_Trigger_Property_Names()
        {
            var source = new TestClass {MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24};
            var destination = source.WithPropertyNameTrigger("MyDate", x => x ?? DateTime.Now)
                                    .WithPropertyNameTrigger("MyInt", x => (int) x > 10 ? 10 : x)
                                    .Map<TestClassDTO>();
                
              
            Assert.IsTrue(destination.MyDate.HasValue);
            Assert.AreEqual(destination.MyInt, 10);
        }

        [TestMethod]
        public void Copy_And_Transform_Parameter_Constructor_On_Trigger_Property_Names()
        {
            var source = new ClassWithNoDefaultConstructorX(5);
            var destination = new ClassWithNoDefaultConstructorX(7);

            source.WithPropertyNameTrigger("X", x => (int) x*(int) x)
                .Map(destination);

            Assert.AreEqual(destination.X, 25);
        }

        [TestMethod]
        public void Copy_Default_Constructor_With_Alias()
        {
            var source = new TestClass {MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24};

            var destination = source.WithAlias("SpecialName", "MyInt2")
                                    .Map <TestClassDTO>();

            Assert.AreEqual(destination.SpecialName, source.MyInt2);
        }

        [TestMethod]
        public void Copy_Parameter_Constructor_With_Alias()
        {
            var source = new ClassWithNoDefaultConstructorX(100);
            var destination = new ClassWithNoDefaultConstructorY(200);

            source.WithAlias("Y", "X")
                .Map(destination);

            Assert.AreEqual(destination.Y, source.X);
        }

        [TestMethod]
        public void Copy_And_Transform_Parameter_Constructor_On_Trigger_Property_Names_With_Alias()
        {
            var source = new ClassWithNoDefaultConstructorX(5);
            var destination = new ClassWithNoDefaultConstructorY(7);

            source.WithAlias("Y", "X")
                .WithPropertyNameTrigger("X", x => (int) x*(int) x)
                .Map(destination);
               
            Assert.AreEqual(destination.Y, 25);
        }

        [TestMethod]
        public void Copy_And_Transform_Parameter_Constructor_On_Trigger_Property_Names_With_Alias_And_Exclusion()
        {
            var source = new ClassWithNoDefaultConstructorX(5);
            var destination = new ClassWithNoDefaultConstructorY(7);

            source.WithPropertyNameTrigger("X", x => (int) x*(int) x)
                .WithExclusion("X")
                .WithAlias("Y", "X")
                .Map(destination);
                
            
            Assert.AreNotEqual(destination.Y, 25);
        }

        [TestMethod]
        public void Copy_With_Exclusions_Only_Default_Constructor()
        {
            TestClass t = new TestClass();
            TestClass t2 = new TestClass();

            t.MyInt = 1;
            t.MyInt2 = 2;

            t.WithExclusion("MyInt").Map(t2);

            Assert.AreNotEqual(t.MyInt,t2.MyInt);
            Assert.AreEqual(t.MyInt2,t2.MyInt2);
        }

        [TestMethod]
        public void Copy_With_Exclusions_Only_Default_Constructor_With_Ending_Wildcard()
        {
            TestClass t = new TestClass();
            TestClass t2 = new TestClass();

            t.MyInt = 1;
            t.MyInt2 = 2;
            t.MyString = "Test";

            t.WithExclusion("*Int2").Map(t2);

            Assert.AreEqual(t.MyInt, t2.MyInt);
            Assert.AreNotEqual(t.MyInt2, t2.MyInt2);
        }

        [TestMethod]
        public void Map_From_DataTable_With_Alias()
        {
            var dt = CreateTable();
            var list = dt.MapToObjectList<TestClass>(new Aliases {{"MyString", "MYSTRING"}}, null );

           

            Assert.IsTrue(list.ElementAt(0).MyString == "HelloWorld");
            Assert.IsTrue(list.ElementAt(0).MyInt == 42);
            Assert.IsTrue(list.ElementAt(0).MyInt2 == 0);

            Assert.IsTrue(list.ElementAt(1).MyString == "AAA");
            Assert.IsTrue(list.ElementAt(1).MyInt == 100);
            Assert.IsTrue(list.ElementAt(1).MyInt2 == 17);
          
          
        }

        [TestMethod]
        public void Map_From_DataTable_With_Alias_And_DataTrigger()
        {
            var dt = CreateTable();
            var list = dt.MapToObjectList<TestClass>(new DataTypeTriggers{{typeof(int), i=>(int)i+1000}},new Aliases { { "MyString", "MYSTRING" } }, null);



            Assert.IsTrue(list.ElementAt(0).MyString == "HelloWorld");
            Assert.IsTrue(list.ElementAt(0).MyInt == 1042);
            Assert.IsTrue(list.ElementAt(0).MyInt2 == 0);

            Assert.IsTrue(list.ElementAt(1).MyString == "AAA");
            Assert.IsTrue(list.ElementAt(1).MyInt == 1100);
            Assert.IsTrue(list.ElementAt(1).MyInt2 == 1017);


        }

        [TestMethod]
        public void Map_From_DataTable_With_Alias_And_PropertyTrigger()
        {
            var dt = CreateTable();
            var list = dt.MapToObjectList<TestClass>(new PropertyNameTriggers() { { "MYSTRING", s => (string)s + "!!!" }, {"MyInt2", i=>(int)i+1000} }, new Aliases { { "MyString", "MYSTRING" } }, null);



            Assert.IsTrue(list.ElementAt(0).MyString == "HelloWorld!!!");
            Assert.IsTrue(list.ElementAt(0).MyInt == 42);
            Assert.IsTrue(list.ElementAt(0).MyInt2 == 0);

            Assert.IsTrue(list.ElementAt(1).MyString == "AAA!!!");
            Assert.IsTrue(list.ElementAt(1).MyInt == 100);
            Assert.IsTrue(list.ElementAt(1).MyInt2 == 1017);


        }

        [TestMethod]
        public void Map_Enumeration_To_Enumeration()
        {
            var testClasses = new List<TestClass> { new TestClass { MyInt = 1, MyInt2 = 2, MyString = "Hello" }, new TestClass { MyInt = 3, MyInt2 = 4, MyString = "Goodbye" } };
            //var testClassDTOs = new List<TestClassDTO>();

            var testClassDTOs = testClasses.ForGroup().Map<TestClassDTO>().ToList();

            Assert.IsTrue(testClassDTOs[1].MyInt == testClasses[1].MyInt && testClassDTOs[1].MyString == testClasses[1].MyString );

        }

        [TestMethod]
        public void Map_Enumeration_To_Enumeration_With_PropertyTriggers_Alias_And_Exclusions()
        {
            var testClasses = new List<TestClass> { new TestClass { MyInt = 1, MyInt2 = 2, MyString = "Hello", MyDate = DateTime.Now}, new TestClass { MyInt = 3, MyInt2 = 4, MyString = "Goodbye", MyDate = DateTime.Now} };
            //var testClassDTOs = new List<TestClassDTO>();

            var testClassDTOs =
                testClasses.ForGroup()
                    .WithPropertyNameTrigger("MyInt", i => (int) i + 1000)
                    .WithAlias("SpecialName", "MyInt2")
                    .WithExclusion("MyDate")
                    .Map <TestClassDTO>().ToList();




            Assert.IsTrue(testClassDTOs[1].MyInt == 1003 && testClassDTOs[1].MyString == testClasses[1].MyString && testClassDTOs[1].SpecialName == testClasses[1].MyInt2 && testClassDTOs[1].MyDate == null);

        }

        [TestMethod]
        public void Map_Enumeration_To_Enumeration_With_DataTriggers_Alias_And_Exclusions()
        {
            var testClasses = new List<TestClass> { new TestClass { MyInt = 1, MyInt2 = 2, MyString = "Hello", MyDate = DateTime.Now }, new TestClass { MyInt = 3, MyInt2 = 4, MyString = "Goodbye", MyDate = DateTime.Now } };
            //var testClassDTOs = new List<TestClassDTO>();

            var testClassDTOs =
                testClasses.ForGroup()
                    .WithTypeTrigger(typeof (int), i => (int) i + 7000)
                    .WithAlias("SpecialName", "MyInt2")
                    .WithExclusion("MyDate")
                    .Map<TestClassDTO>()
                    .ToList();

         
          

            Assert.IsTrue(testClassDTOs[1].MyInt == 7003 && testClassDTOs[1].SpecialName == 7004 && testClassDTOs[1].MyString == testClasses[1].MyString && testClassDTOs[1].MyDate == null);

        }

        [TestMethod] 
        public void Copy_With_Alias_Using_Lambda()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24 };

            var destination = source.WithAlias<TestClassDTO, TestClass>(d=>d.SpecialName, s=>s.MyInt2)
                                    .Map<TestClassDTO>();

            Assert.AreEqual(destination.SpecialName, source.MyInt2);
        }

        [TestMethod]
        public void Copy_With_Exclusion_Using_Lambda()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24 };

            var destination = source.WithExclusion<TestClass>(t=>t.MyInt)
                                    .Map<TestClassDTO>();

            Assert.AreNotEqual(destination.MyInt, source.MyInt);
        }

        [TestMethod]
        public void Map_Enumeration_To_Enumeration_With_PropertyTriggers_Alias_And_Exclusions_Using_Lambda_In_Alias_And_Exclusion()
        {
            var testClasses = new List<TestClass> { new TestClass { MyInt = 1, MyInt2 = 2, MyString = "Hello", MyDate = DateTime.Now }, new TestClass { MyInt = 3, MyInt2 = 4, MyString = "Goodbye", MyDate = DateTime.Now } };
            //var testClassDTOs = new List<TestClassDTO>();

            var testClassDTOs =
                testClasses.ForGroup()
                    .WithPropertyNameTrigger("MyInt", i => (int)i + 1000)
                    .WithAlias("SpecialName", "MyInt2")
                    .WithExclusion<TestClass>(t=>t.MyDate)
                    .Map<TestClassDTO>().ToList();

            Assert.IsTrue(testClassDTOs[1].MyInt == 1003 && testClassDTOs[1].MyString == testClasses[1].MyString && testClassDTOs[1].SpecialName == testClasses[1].MyInt2 && testClassDTOs[1].MyDate == null);

        }

        [TestMethod]
        public void Map_Enumeration_To_Enumeration_With_PropertyTriggers_Alias_And_Exclusions_Using_Lambda_In_Alias()
        {
            var testClasses = new List<TestClass> { new TestClass { MyInt = 1, MyInt2 = 2, MyString = "Hello", MyDate = DateTime.Now }, new TestClass { MyInt = 3, MyInt2 = 4, MyString = "Goodbye", MyDate = DateTime.Now } };
            //var testClassDTOs = new List<TestClassDTO>();

            var testClassDTOs =
                testClasses.ForGroup()
                    .WithPropertyNameTrigger("MyInt", i => (int)i + 1000)
                    .WithAlias("SpecialName", "MyInt2")
                    .WithExclusion("MyDate")
                    .Map<TestClassDTO>().ToList();

            Assert.IsTrue(testClassDTOs[1].MyInt == 1003 && testClassDTOs[1].MyString == testClasses[1].MyString && testClassDTOs[1].SpecialName == testClasses[1].MyInt2 && testClassDTOs[1].MyDate == null);

        }

        [TestMethod]
        public void Copy_With_Alias_And_PropertyNameTrigger_Using_Lambda()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24 };

            var destination = source
                .WithAlias<TestClassDTO, TestClass>(t=>t.SpecialName, t=>t.MyInt2)
                .WithPropertyNameTrigger<TestClass>(t => t.MyInt2, o => (int) o + 1000)
                .Map<TestClassDTO>();

            Assert.AreEqual(destination.SpecialName, 1024);
        }

        [TestMethod]
        public void Copy_And_Flatten()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass{MyInt = 100}};

            var destination = source.Flatten("Child").Map<TestClassDTO>();

            Assert.AreEqual(destination.ChildMyInt, source.Child.MyInt);
        }

        [TestMethod]
        public void Copy_And_Flatten_With_Expression()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } };

            var destination = source.Flatten<TestClass>(t=>t.Child).Map<TestClassDTO>();

            Assert.AreEqual(destination.ChildMyInt, source.Child.MyInt);
        }
        [TestMethod]
        public void Copy_And_Flatten_With_Alt_Prefix()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } };

            var destination = source.Flatten("Child", "C").Map<TestClassDTO>();

            Assert.AreEqual(destination.CMyInt, source.Child.MyInt);
        }

        [TestMethod]
        public void Copy_And_Flatten_With_Alt_Prefix_Using_Expression()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } };

            var destination = source.Flatten<TestClass>(t=>t.Child, "C").Map<TestClassDTO>();

            Assert.AreEqual(destination.CMyInt, source.Child.MyInt);
        }
        [TestMethod]
        public void Copy_And_Flatten_With_Exclusion()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } };

            var destination = source.Flatten("Child", "Child", new List<string>{"ChildMyInt"}).Map<TestClassDTO>();

            Assert.AreNotEqual(destination.ChildMyInt, source.Child.MyInt);
        }

        [TestMethod]
        public void Copy_And_Flatten_With_Exclusion_Using_Expression()
        {
            var source = new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } };

            var destination = source.Flatten<TestClass>(c=>c.Child, "Child", new List<string> { "ChildMyInt" }).Map<TestClassDTO>();

            Assert.AreNotEqual(destination.ChildMyInt, source.Child.MyInt);
        }
        [TestMethod]
        public void Copy_And_Flatten_Enumeration()
        {
            var source = new List<TestClass>{new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } }};

            var destination = source.ForGroup().Flatten("Child").Map<TestClassDTO>();

            Assert.AreEqual(destination.First().ChildMyInt, source[0].Child.MyInt);
        }
        [TestMethod]
        public void Copy_And_Flatten_Enumeration_Using_Expression()
        {
            var source = new List<TestClass> { new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } } };

            var destination = source.ForGroup().Flatten<TestClass>(t=>t.Child).Map<TestClassDTO>();

            Assert.AreEqual(destination.First().ChildMyInt, source[0].Child.MyInt);
        }

        [TestMethod]
        public void Copy_And_Flatten_With_Alt_Prefix_Enumeration()
        {
            var source = new List<TestClass> { new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } } };

            var destination = source.ForGroup().Flatten("Child", "C").Map<TestClassDTO>();

            Assert.AreEqual(destination.First().CMyInt, source[0].Child.MyInt);
        }

        [TestMethod]
        public void Copy_And_Flatten_With_Alt_Prefix_Enumeration_Using_Expression()
        {
            var source = new List<TestClass> { new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } } };

            var destination = source.ForGroup().Flatten<TestClass>(t=>t.Child, "C").Map<TestClassDTO>();

            Assert.AreEqual(destination.First().CMyInt, source[0].Child.MyInt);
        }

        [TestMethod]
        public void Copy_And_Flatten_With_Exclusion_Enumeration()
        {
            var source = new List<TestClass> { new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } } };

            var destination = source.ForGroup().Flatten("Child", "Child", new List<string> { "ChildMyInt" }).Map<TestClassDTO>();

            Assert.AreNotEqual(destination.First().ChildMyInt, source[0].Child.MyInt);
        }

        [TestMethod]
        public void Copy_And_Flatten_With_Exclusion_Enumeration_Using_Enumeration()
        {
            var source = new List<TestClass> { new TestClass { MyDate = DateTime.Parse("1/1/2001"), MyInt = 42, MyInt2 = 24, Child = new TestClass { MyInt = 100 } } };

            var destination = source.ForGroup().Flatten<TestClass>(t=>t.Child, "Child", new List<string> { "ChildMyInt" }).Map<TestClassDTO>();

            Assert.AreNotEqual(destination.First().ChildMyInt, source[0].Child.MyInt);
        }
        [TestMethod]
        public void Map_Enumeration_To_Enumeration_With_PropertyTriggers_Alias_And_Exclusions_And_PropertyNameTrigger_Using_Lambda_In_Alias()
        {
            var testClasses = new List<TestClass> { new TestClass { MyInt = 1, MyInt2 = 2, MyString = "Hello", MyDate = DateTime.Now }, new TestClass { MyInt = 3, MyInt2 = 4, MyString = "Goodbye", MyDate = DateTime.Now } };
            //var testClassDTOs = new List<TestClassDTO>();

            var testClassDTOs =
                testClasses.ForGroup()
                    .WithPropertyNameTrigger<TestClass>(t=>t.MyInt, i => (int)i + 1000)
                    .WithAlias("SpecialName", "MyInt2")
                    .WithExclusion("MyDate")
                    .Map<TestClassDTO>().ToList();

            Assert.IsTrue(testClassDTOs[1].MyInt == 1003 && testClassDTOs[1].MyString == testClasses[1].MyString && testClassDTOs[1].SpecialName == testClasses[1].MyInt2 && testClassDTOs[1].MyDate == null);

        }

        [TestMethod]
        public void Copy_Parameter_Constructor_With_AliasTrigger()
        {
            var source = new ClassWithNoDefaultConstructorX(100);
            var destination = new ClassWithNoDefaultConstructorY(200);

            source.WithAliasTrigger("Y", "X", o => (int) o + 1000).Map(destination);
                

            Assert.AreEqual(destination.Y, source.X + 1000);
        }

        [TestMethod]
        public void Copy_Parameter_Constructor_With_AliasTrigger_UsingLambda()
        {
            var source = new ClassWithNoDefaultConstructorX(100);
            var destination = new ClassWithNoDefaultConstructorY(200);

            source.WithAliasTrigger<ClassWithNoDefaultConstructorY, ClassWithNoDefaultConstructorX>(d=>d.Y, s=>s.X, o => (int)o + 1000).Map(destination);


            Assert.AreEqual(destination.Y, source.X + 1000);
        }

        [TestMethod]
        public void Copy_Parameter_Constructor_With_AliasTrigger_Enumeration()
        {
            var testClasses = new List<TestClass> { new TestClass { MyInt = 1, MyInt2 = 2, MyString = "Hello", MyDate = DateTime.Now }, new TestClass { MyInt = 3, MyInt2 = 4, MyString = "Goodbye", MyDate = DateTime.Now } };

            var destination =
                testClasses.ForGroup().WithAliasTrigger("SpecialName", "MyInt2", o => (int) o + 1000).Map<TestClassDTO>().ToList();

            Assert.IsTrue(destination[1].SpecialName == testClasses[1].MyInt2 + 1000);
        }

        [TestMethod]
        public void Copy_Parameter_Constructor_With_AliasTrigger_Enumeration_Using_Lambda()
        {
            var testClasses = new List<TestClass> { new TestClass { MyInt = 1, MyInt2 = 2, MyString = "Hello", MyDate = DateTime.Now }, new TestClass { MyInt = 3, MyInt2 = 4, MyString = "Goodbye", MyDate = DateTime.Now } };

            var destination =
                testClasses.ForGroup().WithAliasTrigger<TestClassDTO, TestClass>(d=>d.SpecialName, s=>s.MyInt2, o => (int)o + 1000).Map<TestClassDTO>().ToList();

            Assert.IsTrue(destination[1].SpecialName == testClasses[1].MyInt2 + 1000);
        }
        
        private DataTable CreateTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("MYSTRING", typeof (string));
            dt.Columns.Add("MyInt", typeof(int));
            dt.Columns.Add("MyInt2", typeof(int));

            var dr = dt.NewRow();
            dr["MYSTRING"] = "HelloWorld";
            dr["MyInt"] = 42;
            dr["MyInt2"] = DBNull.Value;
            dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["MYSTRING"] = "AAA";
            dr["MyInt"] = 100;
            dr["MyInt2"] = 17;

            dt.Rows.Add(dr);

            return dt;
        }
    }
}